package com.memory.monitor.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.memory.monitor.common.BaseResponse;
import com.memory.monitor.common.DeleteRequest;
import com.memory.monitor.common.ErrorCode;
import com.memory.monitor.common.ResultUtils;
import com.memory.monitor.constant.ExcelConstant;
import com.memory.monitor.exception.BusinessException;
import com.memory.monitor.exception.ThrowUtils;
import com.memory.monitor.job.AreaExcelListener;
import com.memory.monitor.mapper.AreaMapper;
import com.memory.monitor.mapper.InstitutionMapper;
import com.memory.monitor.model.dto.area.AreaAddRequest;
import com.memory.monitor.model.dto.area.AreaQuerryRequest;
import com.memory.monitor.model.dto.area.AreaUpdateRequest;
import com.memory.monitor.model.dto.institution.InstitutionQueryRequest;
import com.memory.monitor.model.dto.institution.InstitutionUpdateRequest;
import com.memory.monitor.model.entity.Area;

import com.memory.monitor.model.entity.Institution;
import com.memory.monitor.model.entity.User;
import com.memory.monitor.model.vo.AreaVO;

import com.memory.monitor.model.vo.UserVO;
import com.memory.monitor.service.AreaService;
import com.memory.monitor.service.InstitutionService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static com.memory.monitor.constant.ExcelConstant.*;
import static com.memory.monitor.job.UserExcelListener.CACHED_DATA_LIST;


/**
* @author 21731
* @description 针对表【area(区域管理)】的数据库操作Service实现
* @createDate 2024-09-02 09:29:52
*/
@Service
public class AreaServiceImpl extends ServiceImpl<AreaMapper, Area> implements AreaService {
    @Resource
    private InstitutionService institutionService;
    @Resource
    private InstitutionMapper institutionMapper;
    /**
     * 封装AreaVO对象
     * @param area
     * @return
     */
    @Override
    public AreaVO getAreaVO(Area area) {
        if (area == null) {
            return null;
        }
        AreaVO areaVO = new AreaVO();
        BeanUtils.copyProperties(area, areaVO);
        return areaVO;
    }

    @Override
    public List<AreaVO> getAreaVO(List<Area> areaList) {
        if (CollectionUtils.isEmpty(areaList)) {
            return new ArrayList<>();
        }
        return areaList.stream().map(this::getAreaVO).collect(Collectors.toList());
    }



    /**
     * 获取用户列表
     */
    @Override
    public List<AreaVO> listAreaByPage() {
        return getAreaVO(this.list());
    }

    /**
     * 查找地区信息
     * @param areaQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<Area> getQueryWrapper(AreaQuerryRequest areaQueryRequest) {
        if (areaQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        Long id = areaQueryRequest.getId();
        String areaName = areaQueryRequest.getAreaName();
        String addressId = areaQueryRequest.getAddressId();
        String type = areaQueryRequest.getType();
        Integer orderId = areaQueryRequest.getOrderId();
        String remark = areaQueryRequest.getRemark();


        QueryWrapper<Area> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(id != null, "id", id);
        queryWrapper.like(StringUtils.isNotBlank(areaName), "area_name", areaName);
        queryWrapper.eq(StringUtils.isNotBlank(addressId), "address_id", addressId);
        queryWrapper.like(StringUtils.isNotBlank(type), "type", type);
        queryWrapper.eq(orderId!=null, "order_id", orderId);
        queryWrapper.eq(StringUtils.isNotBlank(remark), "remark", remark);


        return queryWrapper;
    }

    /**
     * 增加地区信息
     * @param areaAddRequest
     * @return
     */
    @Override
    public Long addArea(AreaAddRequest areaAddRequest) {
        if (areaAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Area area = new Area();

        BeanUtils.copyProperties(areaAddRequest, area);
        boolean result = this.save(area);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return area.getId();
    }

    /**
     * 修改地区信息(修改地域)
     * @param areaUpdateRequest
     * @return
     */
    @Override
    public Boolean updateArea(AreaUpdateRequest areaUpdateRequest) {
        if (areaUpdateRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String areaName = areaUpdateRequest.getAreaName();
        Area area = this.getById(areaUpdateRequest.getId());
        // 如果找不到对应的Area对象，可以选择抛出异常或返回错误
        ThrowUtils.throwIf(area == null,ErrorCode.PARAMS_ERROR);

        // 1.查询关联机构记录
//        QueryWrapper<Institution> iqw = new QueryWrapper<>();
//        iqw.eq(StringUtils.isNotBlank(area.getAreaName()),"area_name", area.getAreaName());
//        List<Institution> institutionList = institutionMapper.selectList(iqw);

        List<Institution> institutionList = institutionService.lambdaQuery()
                .eq(Institution::getArea, area.getAreaName()).list();

        // 2.修改关联机构地域字段
//        for (Institution institution : institutionList) {
//            UpdateWrapper<Institution> iuw = new UpdateWrapper<>();
//            iuw.set("area_name",areaName);
//            boolean update = institutionService.update(institution,iuw);
//            ThrowUtils.throwIf(!update ,ErrorCode.PARAMS_ERROR);
//        }

        for (Institution institution : institutionList) {
            institution.setArea(areaName);
        }
        institutionService.updateBatchById(institutionList);

//        List<Institution> list = institutionList.stream().peek((institution) -> institution.setArea(areaName)).collect(Collectors.toList());
//        institutionService.updateBatchById(list);

        // 3.修改地域
        BeanUtils.copyProperties(areaUpdateRequest,area);
        boolean result = this.updateById(area);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return result;
    }

    /**
     * 删除地区信息
     * @param deleteRequest
     * @return
     */
    @Override
    public Boolean deleteArea(DeleteRequest deleteRequest) {
        if (deleteRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 创建查询请求，设置ID
        Area area = this.getById(deleteRequest.getId());
        // 如果找不到对应的Area对象，可以选择抛出异常或返回错误
        ThrowUtils.throwIf(area == null,ErrorCode.PARAMS_ERROR);

        //在area表中查询areaName相同的字段 进行同步删除
        List<Institution> institutionList = institutionService.lambdaQuery()
                .eq(Institution::getArea, area.getAreaName()).list();

        institutionService.removeBatchByIds(institutionList);

        boolean result = this.removeById(deleteRequest.getId());
        ThrowUtils.throwIf(result, ErrorCode.OPERATION_ERROR);
        return result;


    }

    @Override
    public Boolean readExcel(MultipartFile multipartFile) {
        // 1.转换文件为字节流
        InputStream inputStream;
        try {
            inputStream = multipartFile.getInputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 2.执行文件处理逻辑
        EasyExcel.read(inputStream, Area.class, new AreaExcelListener()).sheet().doRead();
        // 3.入库
        boolean saveBatch = this.saveBatch(AreaExcelListener.CACHED_DATA_LIST);

        ThrowUtils.throwIf(!saveBatch, ErrorCode.PARAMS_ERROR);
        return true;
    }



    @Override
    public Boolean writeExcel(String path) {
        // 1.定义文件路径
        String fullPath = DOWNLOAD_PATH + AREA_TABLE_NAME;
        // 2.检查文件是否存在
        ExcelConstant.isExist(fullPath);
        // 3.根据路径导出
        List<AreaVO> AreaList = this.listAreaByPage();
        EasyExcel.write(fullPath, User.class).sheet(AREA_SHEET_NAME).doWrite(AreaList);

        return true;
    }
}






